package io.feige.rpc.consumer.network.handler;

import io.feige.rpc.protocol.nettyobj.pojo.Ping;
import io.feige.rpc.protocol.nettyobj.pojo.Pong;

import java.net.SocketTimeoutException;

import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.DefaultExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler;
import org.jboss.netty.handler.timeout.IdleStateEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 

public class StateCheckChannelHandler extends IdleStateAwareChannelHandler {

	private Logger logger = LoggerFactory.getLogger(StateCheckChannelHandler.class);    
	
	private volatile boolean pingResponsed=true;
	
	@Override
	public void channelIdle(ChannelHandlerContext ctx, IdleStateEvent e) throws Exception {
		if (!pingResponsed) {
			logger.debug("connection time out {}, {}", e.getChannel(), this);
			handleUpstream(ctx, new DefaultExceptionEvent(e.getChannel(), new SocketTimeoutException())); 
			e.getChannel().close();
		}else{
			pingResponsed=false;
			logger.debug("channelIdle write ping message {}, writable {}", e.getChannel(), e.getChannel().isWritable());
			ChannelFuture future = e.getChannel().write(new Ping());
			future.addListener(new ChannelFutureListener() {
				
				@Override
				public void operationComplete(ChannelFuture future) throws Exception {
					logger.debug("ping operationComplete {}, isSuccess {}", future.getChannel(), future.isSuccess());
				}
			});
			logger.debug("write ping message ok {}", e.getChannel());
		}
		super.channelIdle(ctx, e);
	}

	
	@Override
	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
			throws Exception {
		logger.debug("received response message {}, {}", e.getMessage(), e.getChannel());
		if (e.getMessage() instanceof Pong) {
			pingResponsed=true;
			logger.debug("received pong packet {}", e.getChannel());
		}else{
			super.messageReceived(ctx, e);
		}
	}
 
}